from typing import Any

from peewee import *
from src.models.BaseModel import BaseModel
from src.util.Model2Dict import m2d
from src.entry.Entrys import Page
from src.util.ParamUtil import formatParam

""" 系统用户 """


class User(BaseModel):
    uId = BigIntegerField(primary_key=True, column_name='u_id')
    username = CharField(max_length=25)
    password = CharField(max_length=255)
    initTime = DateTimeField(column_name='init_time')
    nickname = CharField(max_length=50)
    status = CharField(max_length=2)
    email = CharField(max_length=30)
    head = CharField(max_length=255)
    sex = CharField(max_length=10)
    phone = CharField(max_length=25)

    class Meta:
        table_name = "sys_user"

    # 根据用户id获取某个用户信息
    @staticmethod
    def getUserById(u_id, pwd: bool = False) -> dict | None | Any:
        results = User.select().where(User.uId == u_id).dicts().execute()
        if len(results) <= 0:
            return None
        results = m2d(results)[0]
        if pwd:
            return results
        return formatParam(results, ['password'])

    # 根据用户名检查用户是否存在
    @staticmethod
    def hasUserByUsername(name):
        return User.select().where(User.username == name).count() > 0

    # 根据账号以及密码查看用户是否存在
    @staticmethod
    def hasUserByUP(uname, pwd):
        r = User.select().where(User.username == uname, User.password == pwd).dicts()
        if len(r) > 0:
            r = m2d(r)[0]
            del r["password"]
            return r
        return None

    # 添加用户
    @staticmethod
    def addUser(data: dict):
        return User.insert(data).execute()

    # 根据用户id删除用户
    @staticmethod
    def delUserById(ids: list[int]):
        return User.delete().where(User.uId.in_(ids)).execute()

    # 根据用户名获取用户信息
    @staticmethod
    def getUserByUsername(username) -> dict | None:
        results = User.select().where(User.username == username).dicts().execute()
        if len(results) > 0:
            return formatParam(m2d(results)[0], ['password'])
        else:
            return None

    # 获取所有用户
    @staticmethod
    def getAll():
        results = User.select().dicts()
        return m2d(results)

    # 查询所有用户信息（分页）
    @staticmethod
    def getAllUser(page: Page = Page(), cdn=None):
        if cdn is None:
            cdn = dict()
        query = User.select()
        if cdn.get('username'):
            query = query.where(User.username.startswith(cdn.get('username')))
        if cdn.get('sex'):
            query = query.where(User.sex == cdn.get('sex'))
        if cdn.get('status'):
            query = query.where(User.status == cdn.get('status'))
        if cdn.get('nickname'):
            query = query.where(User.nickname.contains(cdn.get('nickname')))
        if cdn.get("initTime"):
            t: list[str] = cdn.get('initTime')
            if t[0]:
                query = query.where(User.initTime > t[0])
            if t[1]:
                query = query.where(User.initTime < t[1])
        if cdn.get('order'):
            order: dict = cdn.get('order')
            if order.get('time') and order.get('time') == 'asc':
                query = query.order_by(User.initTime.asc())
            if order.get('time') and order.get('time') == 'desc':
                query = query.order_by(User.initTime.desc())
        r = query.paginate(page.num, page.size).dicts()
        page.count = query.count()
        page.rows = m2d(r)
        return page.__dict__

    # 更新用户数据
    @staticmethod
    def updateById(u_id, k):
        return User.update(k).where(User.uId == u_id).execute() > 0

    # 判断是否拥有该用户
    @staticmethod
    def hasUser(uid) -> bool:
        return User.select(User.uId).where(User.uId == uid).count() > 0


""" 系统状态 """


class UserStatus(BaseModel):
    id = BigIntegerField(primary_key=True, column_name='id')
    uId = BigIntegerField(db_column='u_id')
    lockTime = DateTimeField(db_column='time')
    loginNum = IntegerField(db_column='login_num')
    lastTime = DateTimeField(db_column='last_time')

    class Meta:
        table_name = "sys_user_status"

    # 删除所有有uid 的映射关系
    @staticmethod
    def delUserStatusInUid(uid: list[int]):
        return UserStatus.delete().where(UserStatus.uId.in_(uid)).execute()


""" 用户角色映射 """


class UserRoleMapping(BaseModel):
    uId = BigIntegerField(db_column='u_id')
    rId = BigIntegerField(db_column='r_id')

    class Meta:
        table_name = 'sys_user_role'

    # 获取某个用户的角色ids
    @staticmethod
    def getUserRoles(u_id):
        roles = UserRoleMapping.select(UserRoleMapping.rId).where(UserRoleMapping.uId == u_id).dicts().execute()
        return [item['rId'] for item in m2d(roles)]

    # 删除用户的角色
    @staticmethod
    def delUserRole(uid: int, rids: list[int]):
        d = UserRoleMapping.delete()
        if len(rids) > 0:
            d = d.where(UserRoleMapping.rId.in_(rids))
        d = d.where(UserRoleMapping.uId == uid)
        count = d.execute()
        if count > 0:
            return True
        return False

    # 删除所有有rid 的映射关系
    @staticmethod
    def delUserRoleInRid(rid: list[int]):
        return UserRoleMapping.delete().where(UserRoleMapping.rId.in_(rid)).execute()

    # 删除所有有uid 的映射关系
    @staticmethod
    def delUserRoleInUid(u_ids: list[int]):
        return UserRoleMapping.delete().where(UserRoleMapping.uId.in_(u_ids)).execute()

    # 为用户添加某个角色
    @staticmethod
    def addUserRole(uid: int, rids: list[int]):
        d = list()
        for item in rids:
            d.append({"uId": uid, "rId": item})
        if len(d) > 0:
            UserRoleMapping.insert_many(d).execute()
        return True

    # 判断用户是否拥有某个角色
    @staticmethod
    def hasUserRole(u_id: int, rid: int) -> bool:
        if UserRoleMapping.select(UserRoleMapping.rId).where(UserRoleMapping.uId == u_id,
                                                             UserRoleMapping.rId == rid).count() > 0:
            return True
        return False
